﻿#include <QCoreApplication>

#include"you.cpp"
#include"down.cpp"
#include"up.cpp"
Point center;
RotatedRect center_ellipse_rect;



Mat getBigmask(Mat src){

  equalizeHist(src, src);
  threshold(src, src, 185, 255, 0);

//  namedWindow("threshold",WINDOW_FREERATIO);
//  imshow("threshold",src);

  Mat hline = getStructuringElement(MORPH_RECT, Size(13, 13), Point(-1, -1));
  erode(src, src, hline);
  dilate(src, src, hline);

//  namedWindow("hline",WINDOW_FREERATIO);
//  imshow("hline",src);

  Canny(src, src, 50, 200);

//  namedWindow("Canny",WINDOW_FREERATIO);
//  imshow("Canny",src);

  Mat hline1 = getStructuringElement(MORPH_RECT, Size(13, 13), Point(-1, -1));
  dilate(src, src, hline1);
//  erode(src, src, hline1);

//  namedWindow("dilate",WINDOW_FREERATIO);
//  imshow("dilate",src);



     std::vector<std::vector<cv::Point>> contours;
      std::vector<cv::Vec4i> hierarchy;
      Mat mask = Mat::zeros(src.rows,src.cols,src.type());
    //只输出最顶层轮廓
    findContours(src, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, cv::Point());
    cv::RotatedRect ellipse_rect;
    for (int i = 0; i < contours.size(); i++)
    {

      if(contours[i].size() > 15)
      {
         ellipse_rect = fitEllipse(contours[i]);
         cv::Scalar color;
                 color = cv::Scalar(50,128,200);
         int w = ellipse_rect.size.width;
         int h = ellipse_rect.size.height;
         if(w<src.cols/3||h<src.rows/3)
           continue;
         ellipse(src, ellipse_rect, color, 2, 8);
         ellipse(mask, ellipse_rect, cv::Scalar(255,128,200), 2, 8);
         center_ellipse_rect = ellipse_rect;
      }
    }

//    namedWindow("ellipse",WINDOW_FREERATIO);
//    imshow("ellipse",src);

    floodFill(mask, cv::Point(ellipse_rect.center.x, ellipse_rect.center.y), Scalar(255, 255, 255));

//    namedWindow("mask",WINDOW_FREERATIO);
//    imshow("mask",mask);
    return mask;
}


Mat getDragon(Mat src111){
  Mat src = src111.clone();
//  equalizeHist(src, src);
  threshold(src, src, 150, 255, 0);

//  namedWindow("threshold",WINDOW_FREERATIO);
//  imshow("threshold",src);

     std::vector<std::vector<cv::Point>> contours;
      std::vector<cv::Vec4i> hierarchy;

    findContours(src, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
    Mat src1 = Mat::zeros(src.rows,src.cols,CV_8UC3);
    Mat mask = Mat::zeros(src.rows,src.cols,CV_8UC1);
    std::cout<<(contours.size())<<endl;

    cv::RotatedRect ellipse_rect;
    for (int i = 0; i < contours.size(); i++)
    {

      if(contours[i].size() > 200)
      {
        if(contours[i].size() > 1000) continue;
        drawContours(src1, contours, i, cv::Scalar(128,0,128), 1, 8, hierarchy, 0);
         ellipse_rect = fitEllipse(contours[i]);
         cv::Scalar color;
         color = cv::Scalar(50,128,200);

        Moments  mo = moments(contours[i], false);

        Point moCenter = Point2f(mo.m10 / mo.m00, mo.m01 / mo.m00);

        int distant = abs(moCenter.y - center_ellipse_rect.center.y)+abs(moCenter.x - center_ellipse_rect.center.x);

        if (distant >center_ellipse_rect.size.height/3) continue;
        circle(src1, moCenter, 2, color,2);
        ellipse(src1, ellipse_rect, color, 2, 8);
        drawContours(mask, contours, i, cv::Scalar(255,0,128), 1, 8, hierarchy, 0);
        floodFill(mask, moCenter, Scalar(255, 255, 255));
      }
    }

//    namedWindow("ellipse",WINDOW_FREERATIO);
//    imshow("ellipse",src1);
//    namedWindow("mask_image",WINDOW_FREERATIO);
//    imshow("mask_image",mask);

    return mask;
}

Mat groupDragon(Mat src){
   Mat src1 = src.clone();
   Mat dilate_kel = getStructuringElement(MORPH_RECT, Size(50, 50), Point(-1, -1));
   Mat erode_kel = getStructuringElement(MORPH_RECT, Size(20, 20), Point(-1, -1));
   dilate(src1, src1, dilate_kel);
   erode(src1, src1, erode_kel);

   std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Vec4i> hierarchy;
   findContours(src1, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
   Mat mask = Mat::zeros(src1.rows,src1.cols,CV_8UC1);

   cv::RotatedRect ellipse_rect;
   vector<vector<Point>> convex(contours.size());
   for (int i = 0; i < contours.size(); i++)
   {
//        ellipse_rect = fitEllipse(contours[i]);
        cv::Scalar color;
        color = cv::Scalar(50,128,200);
        convexHull(contours[i], convex[i]);
        drawContours(mask, convex, i, Scalar(255, 255, 255), 2, 8);

       Moments  mo = moments(convex[i], false);

       Point moCenter = Point2f(mo.m10 / mo.m00, mo.m01 / mo.m00);
       floodFill(mask, moCenter, Scalar(175, 255, 255));

   }
     return mask;

}
Point char_center;
Mat del_char(Mat src){
  Mat Left =src.clone();
  threshold(Left, Left, 255, 255,THRESH_BINARY_INV| THRESH_OTSU);
  namedWindow("THRESH_OTSU-char",WINDOW_FREERATIO);
  imshow("THRESH_OTSU-char",Left);

  Mat Left1 = Left.clone();
  Mat dilate_kel = getStructuringElement(MORPH_RECT, Size(1, 30), Point(-1, -1));

  dilate(Left1, Left1, dilate_kel);
  Mat erode_kel = getStructuringElement(MORPH_RECT, Size(3, 15), Point(-1, -1));
  erode(Left1, Left1, erode_kel);

  namedWindow("close_char",WINDOW_FREERATIO);
  imshow("close_char",Left1);

  std::vector<std::vector<cv::Point>> contours;
   std::vector<cv::Vec4i> hierarchy;
  findContours(Left1, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point());
  Mat mask = Mat::zeros(Left1.rows,Left1.cols,CV_8UC1);
  Mat mask1 = Left.clone();
  if(mask1.channels()!=1)
  cvtColor(mask1,mask1,COLOR_GRAY2BGR);


  cv::RotatedRect ellipse_rect;
  vector<vector<Point>> convex(contours.size());
  for (int i = 0; i < contours.size(); i++)
  {
//        ellipse_rect = fitEllipse(contours[i]);
    if( contours[i].size()<300){
      continue;
    }
    if(contourArea(contours[i])>100000)continue;;
       cv::Scalar color;
       color = cv::Scalar(50,128,200);
       convexHull(contours[i], convex[i]);
       drawContours(mask, contours, i, Scalar(255, 255, 255), 2, 8);

       drawContours(mask1, convex, i, Scalar(255, 0, 255), 2, 8);
       drawContours(mask1, contours, i, Scalar(255, 255, 0), 2, 8);

      Moments  mo = moments(contours[i], false);

      Point moCenter = Point2f(mo.m10 / mo.m00, mo.m01 / mo.m00);
      char_center =moCenter;
      floodFill(mask, moCenter, Scalar(255, 255, 255));

  }
//  namedWindow("Left1111",WINDOW_FREERATIO);
//  imshow("Left1111",mask1);
  namedWindow("del_char",WINDOW_FREERATIO);
  imshow("del_char",mask);
    return mask;

}
int main(int argc, char *argv[])
{
  QCoreApplication a(argc, argv);
  cv::Mat src = cv::imread("E:/workspace/qt/DaHeng/ng/ng09.bmp");
  Mat mask_you =  you(src);

  resize(src,src,Size(src.cols*3,src.rows*3));
  Mat big_src1 = src.clone();
  namedWindow("src",WINDOW_FREERATIO);
  imshow("src",src);

  if(src.channels()!=1)
  cvtColor(src, src, COLOR_BGR2GRAY);
  Mat ori = src.clone();
  //得到大圆
  Mat mask = getBigmask(src);
  namedWindow("mask",WINDOW_FREERATIO);
  imshow("mask",mask);

   Mat big_src = ori & ~mask;
   namedWindow("ori & ~mask",WINDOW_FREERATIO);
   imshow("ori & ~mask",big_src);


  //裁剪 只保留中心椭圆左侧的点
      int x1 = center_ellipse_rect.center.x - center_ellipse_rect.size.width;
      int x2 = center_ellipse_rect.center.x;
      int y1 = center_ellipse_rect.center.y -center_ellipse_rect.size.height/2.35;
      int y2 = center_ellipse_rect.center.y +center_ellipse_rect.size.height/2.35;
      Rect box = Rect(Point(x1,y1),Point(x2,y2));
   Mat Left = big_src(box).clone();
   namedWindow("big_src21",WINDOW_FREERATIO);
   imshow("big_src21",Left);

   Mat left_wo_char = Mat(Left&(~del_char(Left))).clone();
   namedWindow("left_wo_char",WINDOW_FREERATIO);
   imshow("left_wo_char",left_wo_char);

   //只保留字的右边
    Rect box_char = Rect(Point(char_center.x,0),Point(left_wo_char.cols,left_wo_char.rows));
    Mat char_right = left_wo_char(box_char).clone();
    namedWindow("char_right",WINDOW_FREERATIO);
    imshow("char_right",char_right);

//    imwrite("E:/workspace/qt/DaHeng/ng/char_right2.jpg",char_right);



    Mat updst = up(char_right);
    Mat downdst = down(char_right);

    Mat char_right_mask = Mat::zeros(char_right.rows,char_right.cols,char_right.type());
    downdst.copyTo(char_right_mask(Rect(Point(0,char_right_mask.rows/2),Point(char_right_mask.cols,char_right_mask.rows))));
    updst.copyTo(char_right_mask(Rect(Point(0,0),Point(char_right_mask.cols,char_right_mask.rows/2))));

    Mat left_wo_char_dst = Mat::zeros(left_wo_char.rows,left_wo_char.cols,left_wo_char.type());
    char_right_mask.copyTo(left_wo_char_dst(box_char));

    Mat big_src_dst_left = Mat::zeros(big_src.rows,big_src.cols,big_src.type());
    left_wo_char_dst.copyTo(big_src_dst_left(box));

    namedWindow("big_src_dst",WINDOW_FREERATIO);
    imshow("big_src_dst",big_src_dst_left);
     Mat final_mask = big_src_dst_left+ mask_you;
    namedWindow("big_src_dst",WINDOW_FREERATIO);
    imshow("big_src_dst",final_mask);


    std::vector<cv::Point> points;
     for(int x=0;x<final_mask.rows;++x)
     {
       for(int y=0;y<final_mask.cols;++y)
       {
         uchar a =final_mask.at<uchar>(x,y);
          if (a>0){
           cv::Point pt;
            pt.x=y;
            pt.y=x;
   //         cout<<"asd12312f";
            points.push_back(pt);
          }

         }
       }


     cvtColor(final_mask,final_mask,COLOR_GRAY2BGR);
     cv::RotatedRect rect;
     rect = fitEllipse(points);
     ellipse(final_mask, rect,  Scalar(255, 129, 0), 2, 8);
     ellipse(big_src1, rect,  Scalar(255, 129, 0), 2, 8);

     namedWindow("big_src_dst",WINDOW_FREERATIO);
     imshow("big_src_dst",final_mask);
     namedWindow("big_src11",WINDOW_FREERATIO);
     imshow("big_src11",big_src1);



     //计算位置和面积
     Mat big_src2 = Mat::zeros(ori.rows,ori.cols,CV_8UC1);
     ellipse(big_src2, rect,  Scalar(255, 129, 0), 2, 8);
     big_src2.resize(ori.rows/3,ori.cols/3);

     std::vector<std::vector<cv::Point>> contours;
      std::vector<cv::Vec4i> hierarchy;
      Mat ellipse_mask = Mat::zeros(src.rows,src.cols,CV_8UC1);
      Mat contours_mask = Mat::zeros(src.rows,src.cols,CV_8UC1);
      Mat mask111 = Mat::zeros(src.rows,src.cols,CV_8UC3);
    //只输出最顶层轮廓
      float contours_area;
    findContours(big_src2, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, cv::Point());
    cv::RotatedRect ellipse_rect;
    vector<Moments> mo(contours.size());
    Point2f moCenter;
    for (int i = 0; i < contours.size(); i++)
    {

      if(contours[i].size() > 15)
      {
         ellipse_rect = fitEllipse(contours[i]);
         cv::Scalar color;
                 color = cv::Scalar(50,128,200);
         int w = ellipse_rect.size.width;
         int h = ellipse_rect.size.height;
         int pi = ellipse_rect.angle;

         float contours_area = contourArea(contours[i]);

        cout<<"\n\n"<<"ellipse :"<<"center:"<<ellipse_rect.center<<"  width:"<<w<<"  height:"<<h<<"  angle:"<<pi;
        cout<<"   area:"<<contours_area<<endl;
      }
    }


  return a.exec();
}
